package com.nidu.demo.dept.executor.command;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.cola.dto.Response;
import com.nidu.demo.dept.ability.DepartmentDomainService;
import com.nidu.demo.dept.gateway.DepartmentGateway;
import com.nidu.demo.dept.model.Department;
import com.nidu.demo.user.gateway.UserDepartmentGateway;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 部门删除命令执行器
 *
 * @author auto
 */
@Component
@RequiredArgsConstructor
public class DepartmentDeleteCmdExe {

    private final DepartmentGateway gateway;

    private final DepartmentDomainService domainService;

    private final UserDepartmentGateway userDepartmentGateway;

    public Response execute(Long id) {
        if(id != null){
            this.deleteDepartments(Collections.singleton(id));
        }
        return Response.buildSuccess();
    }

    public Response execute(Set<Long> ids){
        if(!CollUtil.isEmpty(ids)){
            this.deleteDepartments(ids);
        }
        return Response.buildSuccess();
    }

    @Transactional
    private void deleteDepartments(Set<Long> deptIds) {
        Set<Long> allDeleteIds = new HashSet<>();

        for (Long deptId : deptIds) {
            // 1. 子部门校验
            List<Department> children = gateway.getByParentId(deptId);
            domainService.validateChildren(children); // 有启用子菜单将抛异常

            // 2. 汇总要删除的ID
            allDeleteIds.add(deptId);
            if (!children.isEmpty()) {
                allDeleteIds.addAll(children.stream().map(Department::getId).collect(Collectors.toList()));
            }
        }

        // 3. 检查是否被用户引用
        domainService.validateUserUse(allDeleteIds);

        // 4. 删除用户-部门关联
        userDepartmentGateway.removeDeptsUsers(allDeleteIds);

        // 5. 执行逻辑删除
        gateway.deleteByIds(allDeleteIds);
    }
} 